package com.tpsix.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tpsix.util.TreeBuilder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tpsix.domain.SysDept;
import com.tpsix.mapper.SysDeptMapper;
import com.tpsix.service.SysDeptService;
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    @Override
    public List<SysDept> deptTree() {
        List<SysDept> deptList = this.list();
        List<SysDept> rootDepts = deptList.stream()
                .filter(sysDept -> sysDept.getParentId() == 0)
                .peek(sysDept -> sysDept.setLevel(0))
                .collect(Collectors.toList());

        TreeBuilder.deptTreeBuild(rootDepts, deptList);
        return rootDepts;
    }

    @Override
    public List<Integer> deptIds(int deptId) {
        SysDept department = this.getDepartment(deptId);
        List<Integer> deptIdList = new ArrayList<>();
        if (department != null) {
            deptIdList.add(department.getId());
            addDeptIds(deptIdList, department);
        }
        return deptIdList;
    }

    @Override
    public boolean addOrUpdate(SysDept sysDept,String type) {
        if("add".equals(type)){
            sysDept.setCreateTime(LocalDateTime.now());
            sysDept.setUpdateTime(LocalDateTime.now());
            sysDept.setTenantId(null);
        }else {
            sysDept.setUpdateTime(LocalDateTime.now());
        }
        return this.saveOrUpdate(sysDept);
    }

    /**
     * 根据部门ID获取该部门及其下属部门树
     */
    private SysDept getDepartment(Integer deptId) {
        List<SysDept> departments = baseMapper.selectList(Wrappers.<SysDept>lambdaQuery()
                .select(SysDept::getId, SysDept::getName, SysDept::getParentId, SysDept::getSort, SysDept::getCreateTime));
        Map<Integer, SysDept> map = departments.stream().collect(
                Collectors.toMap(SysDept::getId, department -> department));

        for (SysDept dept : map.values()) {
            SysDept parent = map.get(dept.getParentId());
            if (parent != null) {
                List<SysDept> children = parent.getChildren() == null ? new ArrayList<>() : parent.getChildren();
                children.add(dept);
                parent.setChildren(children);
            }
        }
        return map.get(deptId);
    }

    private void addDeptIds(List<Integer> deptIdList, SysDept department) {
        List<SysDept> children = department.getChildren();
        if (children != null) {
            for (SysDept dept : children) {
                deptIdList.add(dept.getId());
                addDeptIds(deptIdList, dept);
            }
        }
    }
}
